using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ViewOn.Kernel;
using ViewOnCore.HostContract;

namespace ViewOn.UI.Dialog
{
    // http://www.un4seen.com/forum/?topic=5877.0
    public partial class EqualizerControl : System.Windows.Controls.UserControl
    {

        #region Variables

        private List<EqualizerPreset> _presets = new List<EqualizerPreset>();

        /*
        private float[] normal_db = new float[] { 0f, 4f, 0.4f, 0.4f, 0.4f, 0.3f, 0.3f, 0.1f, 0.1f, 0.2f };
        private float[] rock_db = new float[] { 4f, 3f, -3f, -4f, -1f, 2f, 4f, 5f, 5f, 5f };
        private float[] full_bass_db = new float[] { 5.9f, 5.9f, 5.9f, 3.6f, 1f, -2.9f, -5.5f, -6.7f, -7f, -7f };
        private float[] full_bass_trebble_db = new float[] { 4.4f, 3.6f, 0f, -4.8f, -3.2f, 1f, 5.1f, 6.7f, 7.4f, 7.4f };
        private float[] full_trebble_db = new float[] { -6.3f, -6.3f, -6.3f, -2.9f, 1.7f, 6.7f, 9.7f, 9.7f, 9.7f, 10.5f };
        */

        #endregion

        #region Constructor

        public EqualizerControl()
        {
            InitializeComponent();

            InitializeEqualizer();
            foreach (EqualizerPreset preset in _presets)
            {
                ComboBoxItem item = new ComboBoxItem();
                item.Content = preset.Name;
                cboPresets.Items.Add(item);
            }
            cboPresets.SelectedIndex = Host.SettingsService.EqualizerPresetIndex;

            UpdateUI();
            SetEnabled();

            chkOn.Checked += new RoutedEventHandler(chkOn_Checked);
            chkOn.Unchecked += new RoutedEventHandler(chkOn_Unchecked);

            cboPresets.SelectionChanged += new SelectionChangedEventHandler(cboPresets_SelectionChanged);
        }

        #endregion

        #region UpdateUI

        private void UpdateUI()
        {
            sliPreamp.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(sliPreamp_ValueChanged);
            sliBalance.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(sliBalance_ValueChanged);
            sli32.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(sli32_ValueChanged);
            sli64.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(sli64_ValueChanged);
            sli125.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(sli125_ValueChanged);
            sli250.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(sli250_ValueChanged);
            sli500.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(sli500_ValueChanged);
            sli1K.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(sli1K_ValueChanged);
            sli2K.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(sli2K_ValueChanged);
            sli4K.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(sli4K_ValueChanged);
            sli8K.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(sli8K_ValueChanged);
            sli16K.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(sli16K_ValueChanged);

            chkOn.IsChecked = Host.SettingsService.IsEqualizerOn;
            BassPlayer.Preamp =0;
            sliBalance.Value = BassPlayer.Balance;
            sliPreamp.Value = BassPlayer.Preamp;
            sli32.Value = BassPlayer.GetEqualizerBandValue(0);
            sli64.Value = BassPlayer.GetEqualizerBandValue(1);
            sli125.Value = BassPlayer.GetEqualizerBandValue(2);
            sli250.Value = BassPlayer.GetEqualizerBandValue(3);
            sli500.Value = BassPlayer.GetEqualizerBandValue(4);
            sli1K.Value = BassPlayer.GetEqualizerBandValue(5);
            sli2K.Value = BassPlayer.GetEqualizerBandValue(6);
            sli4K.Value = BassPlayer.GetEqualizerBandValue(7);
            sli8K.Value = BassPlayer.GetEqualizerBandValue(8);
            sli16K.Value = BassPlayer.GetEqualizerBandValue(9);

            sliPreamp.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sliPreamp_ValueChanged);
            sliBalance.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sliBalance_ValueChanged);
            sli32.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sli32_ValueChanged);
            sli64.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sli64_ValueChanged);
            sli125.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sli125_ValueChanged);
            sli250.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sli250_ValueChanged);
            sli500.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sli500_ValueChanged);
            sli1K.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sli1K_ValueChanged);
            sli2K.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sli2K_ValueChanged);
            sli4K.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sli4K_ValueChanged);
            sli8K.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sli8K_ValueChanged);
            sli16K.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sli16K_ValueChanged);
        }

        #endregion

        #region Check box : on/off

        void chkOn_Checked(object sender, RoutedEventArgs e)
        {
            BassPlayer.IsEqualizerOn = true;
            SetEnabled();
        }

        void chkOn_Unchecked(object sender, RoutedEventArgs e)
        {
            BassPlayer.IsEqualizerOn = false;

            SetEnabled();
        }

        private void SetEnabled()
        {
            sliPreamp.IsEnabled = BassPlayer.IsEqualizerOn;
            sliBalance.IsEnabled = BassPlayer.IsEqualizerOn;
            sli32.IsEnabled = BassPlayer.IsEqualizerOn;
            sli64.IsEnabled = BassPlayer.IsEqualizerOn;
            sli125.IsEnabled = BassPlayer.IsEqualizerOn;
            sli250.IsEnabled = BassPlayer.IsEqualizerOn;
            sli500.IsEnabled = BassPlayer.IsEqualizerOn;
            sli1K.IsEnabled = BassPlayer.IsEqualizerOn;
            sli2K.IsEnabled = BassPlayer.IsEqualizerOn;
            sli4K.IsEnabled = BassPlayer.IsEqualizerOn;
            sli8K.IsEnabled = BassPlayer.IsEqualizerOn;
            sli16K.IsEnabled = BassPlayer.IsEqualizerOn;
            cboPresets.IsEnabled = BassPlayer.IsEqualizerOn;
        }

        #endregion

        #region Gain change

        void sliPreamp_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            BassPlayer.Preamp = sliPreamp.Value;
        }

        void sli16K_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            BassPlayer.SetEqualizerBandValue(9, (float)sli16K.Value);
        }

        void sli8K_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            BassPlayer.SetEqualizerBandValue(8, (float)sli8K.Value);
        }

        void sli4K_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            BassPlayer.SetEqualizerBandValue(7, (float)sli4K.Value);
        }

        void sli2K_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            BassPlayer.SetEqualizerBandValue(6, (float)sli2K.Value);
        }

        void sli1K_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            BassPlayer.SetEqualizerBandValue(5, (float)sli1K.Value);
        }

        void sli500_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            BassPlayer.SetEqualizerBandValue(4, (float)sli500.Value);
        }

        void sli250_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            BassPlayer.SetEqualizerBandValue(3, (float)sli250.Value);
        }

        void sli125_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            BassPlayer.SetEqualizerBandValue(2, (float)sli125.Value);
        }

        void sli64_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            BassPlayer.SetEqualizerBandValue(1, (float)sli64.Value);
        }

        void sli32_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            BassPlayer.SetEqualizerBandValue(0, (float)sli32.Value);
        }

        #endregion

        #region Balance

        void sliBalance_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            BassPlayer.Balance = (int)sliBalance.Value;
        }

        #endregion

        #region Presets

        private void InitializeEqualizer()
        {
            _presets.Add(new EqualizerPreset("Default", new float[] { 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f }));
            _presets.Add(new EqualizerPreset("Rock", new float[] { -1f, 1f, 2f, 3f, -1f, -1f, 0f, 0f, 4f, 4f }));
            _presets.Add(new EqualizerPreset("Pop", new float[] { -1f, 2f, 3f, 4f, 3f, -1f, -2f, -1f, -1f, -1f }));
            _presets.Add(new EqualizerPreset("Rap", new float[] { -1f, 0f, 2f, 2f, -1f, -1f, 0f, 0f, 4f, 6f }));
            _presets.Add(new EqualizerPreset("Grunge", new float[] { -4f, 0f, 0f, -2f, 0f, 0f, 2f, 3f, 0f, -3f }));
            _presets.Add(new EqualizerPreset("Metal", new float[] { -4f, 0f, 0f, 0f, 0f, 0f, 3f, 0f, 3f, 1f }));
            _presets.Add(new EqualizerPreset("Dance", new float[] { -1f, 4f, 5f, 1f, -1f, -1f, 0f, 0f, 4f, 4f }));
            _presets.Add(new EqualizerPreset("Techno", new float[] { -6f, 1f, 4f, -1f, -1f, -2f, 0f, 0f, 5f, 5f }));
            _presets.Add(new EqualizerPreset("Country", new float[] { -1f, 0f, 0f, 2f, 2f, 0f, 0f, 0f, 3f, 3f }));
            _presets.Add(new EqualizerPreset("Jazz", new float[] { 0f, 0f, 0f, 3f, 3f, 3f, 0f, 2f, 4f, 4f }));
            _presets.Add(new EqualizerPreset("Acoustic", new float[] { 0f, 1f, 2f, 0f, 0f, 0f, 0f, 0f, 2f, 2f }));
            _presets.Add(new EqualizerPreset("Folk", new float[] { -1f, 0f, 1f, 0f, 2f, 0f, 0f, 0f, 2f, 0f }));
            _presets.Add(new EqualizerPreset("New Age", new float[] { 0f, 3f, 3f, 0f, 0f, 0f, 0f, 0f, 1f, 1f }));
            _presets.Add(new EqualizerPreset("Classic", new float[] { 0f, 6f, 6f, 3f, 0f, 0f, 0f, 0f, 2f, 2f }));
            _presets.Add(new EqualizerPreset("Blues", new float[] { -1f, 0f, 2f, 1f, 0f, 0f, 0f, 0f, -1f, -3f }));
            _presets.Add(new EqualizerPreset("Oldies", new float[] { -2f, 0f, 2f, 1f, 0f, 0f, 0f, 0f, -2f, -5f }));
            _presets.Add(new EqualizerPreset("Reggae", new float[] { -1f, 0f, 0f, -1f, 0f, 3f, 4f, 0f, 3f, 4f }));
            _presets.Add(new EqualizerPreset("Opera", new float[] { 0f, 0f, 0f, 3f, 4f, 2f, 5f, 2f, 0f, 0f }));
            _presets.Add(new EqualizerPreset("Swing", new float[] { -1f, 0f, 0f, 0f, 3f, 3f, 0f, 2f, 4f, 4f }));
            _presets.Add(new EqualizerPreset("Voice", new float[] { -2f, 0f, 2f, 1f, 0f, 0f, 0f, 0f, -2f, -5f }));
        }

        void cboPresets_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            LoadPreset(cboPresets.SelectedIndex);
        }

        private void LoadPreset(int presetIndex)
        {
            float[] valuesDb = _presets[presetIndex].ValuesDb;

            for (int index = 0; index < valuesDb.Length; index++)
                BassPlayer.SetEqualizerBandValue(index, valuesDb[index]);

            Host.SettingsService.EqualizerPresetIndex = cboPresets.SelectedIndex;

            UpdateUI();
        }

        #endregion

    }

    #region EqualizerPreset

    sealed public class EqualizerPreset
    {
        public string Name;
        public float[] ValuesDb;

        public EqualizerPreset(string name, float[] valueDb)
        {
            Name = name;
            ValuesDb = valueDb;
        }
    }

    #endregion

}